// 3-3 预处理器-条件编译

/**
 * C++ 预处理器
 * 预处理器是一些指令，指示编译器在实际编译之前所需完成的预处理。

 * 所有的预处理器指令都是以井号（#）开头，只有空格字符可以出现在预处理指令之前。预处理指令**不是 C++ 语句**，所以它们不会以分号（;）结尾。

 * 我们已经看到，之前所有的实例中都有 #include 指令。这个宏用于把头文件包含到源文件中。

 * C++ 还支持很多预处理指令，比如 #include、#define、#if、#else、#line 等，让我们一起看看这些重要指令。
 *
 * --------------------------------------
 * 条件编译
 * 有几个指令可以用来有选择地对部分程序源代码进行编译。这个过程被称为条件编译。

 * 条件预处理器的结构与 if 选择结构很像。请看下面这段预处理器的代码：

        #ifdef NULL
          #define NULL 0
        #endif

 * 您可以只在调试时进行编译，调试开关可以使用一个宏来实现，如下所示：

        #ifdef DEBUG
          cerr <<"Variable x = " << x << endl;
        #endif

 * 如果在指令 #ifdef DEBUG 之前已经定义了符号常量 DEBUG，则会对程序中的 cerr 语句进行编译。您可以使用 #if 0 语句注释掉程序的一部分，如下所示：

          #if 0
            不进行编译的代码
          #endif
        
 * 让我们尝试下面的实例：
*/

#include <iostream>
// #define DEBUG
#define MAX(a, b) (a > b ? a : b)
int main(void)
{
  std::cout << "MAX(3,4)" << MAX(3, 4) << std::endl;
#ifndef DEBUG
#define DEBUG
#endif

#if defined DEBUG
#undef DEBUG
  std::cout << "xxxx" << std::endl;
#endif

#if !defined DEBUG
#define DEBUG
  std::cout << "xxxx" << std::endl;
#endif

#ifdef DEBUG
  std::clog << "[DEBUG]: test" << std::endl;
#endif

#if false
// #if 0
// #if 1
  std::cout << a << std::endl;
#endif

  printf("---------------end------------------\n");
  return 0;
}